package com.share.component;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.share.entity.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @desc:
 * @author:caifan
 * @date:2020/4/6
 */
@Component
@Slf4j
public class MsgReceiver {
    @RabbitListener(queues = {"share.directQueue"})
    @RabbitHandler
//    public void consumerMsg(Message message, Channel channel) throws IOException {
    public void consumerMsg(org.springframework.amqp.core.Message message, Channel channel) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Order order = objectMapper.readValue(message.getBody(), Order.class);
        log.info("消费消息:{}",order);
//        int i = 1 / 0;

        //手工签收
        Long deliveryTag = (Long) message.getMessageProperties().getDeliveryTag();
        log.info("接受deliveryTag:{}",deliveryTag);
        channel.basicAck(deliveryTag,false);//消息确认
    }

    @RabbitListener(queues = {"share.delayQueue"})
    @RabbitHandler
    public void consumerDelayMsg(org.springframework.amqp.core.Message message, Channel channel) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        ObjectMapper objectMapper = new ObjectMapper();
        Order order = objectMapper.readValue(message.getBody(),Order.class);
        log.info("在{},签收:{}",sdf.format(new Date()),order);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }


    /**
     * todo:   强烈不推荐这种用法 我们再开发中需要把队列 交换机  绑定配置到我们专门的配置类中
     * @param message
     * @param channel
     */
   @RabbitListener(bindings =
    @QueueBinding(
            value = @Queue(
                    name = "bootQueue2",
                    durable = "true",
                    autoDelete = "false",
                    exclusive = "false"
            ),
            exchange = @Exchange(
                    name = "springboot.direct.exchange",
                    type = "direct",
                    durable = "true",
                    autoDelete = "false"),
            key = {"springboot.key2"}
    )
    )
    @RabbitHandler
    public void consumerMsg2(Message message,Channel channel) throws IOException {
        log.info("consumerMsg2===消费消息:{}",message.getPayload());
        //手工签收
        Long deliveryTag = (Long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
        log.info("consumerMsg2===接受deliveryTag:{}",deliveryTag);
        channel.basicAck(deliveryTag,false);
    }



     /*rabbitmq.queue.queueName=bootQueue3
     rabbitmq.queue.durable=true
     rabbitmq.queue.autoDelete=false
     rabbitmq.queue.exclusive=false

     rabbitmq.exchange.name=springboot.direct.exchange
     rabbitmq.exchange.type=direct
     rabbitmq.exchange.autoDelete=false
     rabbitmq.exchange.durable=true
     rabbitmq.routing.key=springboot.key3*/
    /* @RabbitListener(bindings =
     @QueueBinding(
     value = @Queue(
     name = "${rabbitmq.queue.queueName}",
     durable = "${rabbitmq.queue.durable}",
     autoDelete = "${rabbitmq.queue.autoDelete}",
     exclusive = "${rabbitmq.queue.exclusive}"
     ),
     exchange = @Exchange(
     name = "${rabbitmq.exchange.name}",
     type = "${rabbitmq.exchange.type}",
     durable = "${rabbitmq.exchange.durable}",
     autoDelete = "${rabbitmq.exchange.autoDelete}"),
     key = {"${rabbitmq.routing.key}"}
     )
     )
     @RabbitHandler
     public void conusmerOrder(@Payload Order order, @Headers Map<String,Object> headers, Channel channel) throws IOException {
     log.info("消费消息order:{}",order.toString());
     log.info("headers:{}",headers);
     Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
     channel.basicAck(deliveryTag,false);
     }
*/


    /**
     * 接受客户端发送的core包下的message
     * @param message
     * @param channel
     * @throws IOException
     */
    /*@RabbitListener(queues = {"bootQueue3"})
    @RabbitHandler
    public void consumerOrder(org.springframework.amqp.core.Message message,Channel channel) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Order order = objectMapper.readValue(message.getBody(),Order.class);
        log.info("order:{}",order.toString());
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }*/


    @RabbitListener(queues = {"bootQueue4"})
    @RabbitHandler
    public void consumerOrder(Message message,Channel channel) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

        Order order = objectMapper.readValue(message.getPayload().toString().getBytes(),Order.class);
        log.info("消费消息:{}",order);
        //手工签收
        Long deliveryTag = (Long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
        log.info("接受deliveryTag:{}",deliveryTag);
        channel.basicAck(deliveryTag,false);
//        channel.basicQos(1);//限流消费
    }

    @RabbitListener(queues = {"share.topicQueue"})
    @RabbitHandler
    public void consumerTopic(org.springframework.amqp.core.Message message,Channel channel) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        Order order = objectMapper.readValue(message.getBody(),Order.class);
//        Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
//        Order order = (Order)jackson2JsonMessageConverter.fromMessage(message);
        log.info("消费消息:{}",order);
        //手工签收
        Long deliveryTag = (Long) message.getMessageProperties().getDeliveryTag();
        log.info("接受deliveryTag:{}",deliveryTag);
        channel.basicAck(deliveryTag,false);
    }
}
